﻿// -----------------------------------------------------------------------
// <copyright file="ModelStateToTempData.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Rosieks.Web.Flow.Internals
{
    using System.Collections.Generic;
    using System.Web.Mvc;
    using Rosieks.Web.Flow.Metadata;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class KeepModelStateAttribute : ActionFilterAttribute
    {
        private const string TempDataKey = "__Webflow_ModelState__";

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var webflowContext = WebflowContext.GetCurrent(filterContext.HttpContext);
            var controller = (Controller)filterContext.Controller;

            if (webflowContext != null)
            {
                if (webflowContext.CurrentElement is NoTransition)
                {
                    controller.TempData[KeepModelStateAttribute.TempDataKey] = controller.ModelState;
                }
                else
                {
                    KeepModelStateAttribute.CopyModelStateFromDictionary(controller.ModelState, controller.TempData);
                }
            }
        }

        private static void CopyModelStateFromDictionary(ModelStateDictionary modelState, IDictionary<string, object> dictionary)
        {
            var modelStateFromDictionary = dictionary[KeepModelStateAttribute.TempDataKey] as ModelStateDictionary;
            if (modelStateFromDictionary != null)
            {
                foreach (var pair in modelStateFromDictionary)
                {
                    ModelState state;
                    if (modelState.TryGetValue(pair.Key, out state))
                    {
                        state.Value = pair.Value.Value;
                        foreach (var error in pair.Value.Errors)
                        {
                            state.Errors.Add(error);
                        }
                    }
                    else
                    {
                        modelState.Add(pair.Key, pair.Value);
                    }
                }
            }
        }
    }
}
